package com.xiaochun.jiankangapp.activity

import android.Manifest
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.RecyclerView.Adapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.bumptech.glide.Glide
import com.xiaochun.jiankangapp.R
import com.xiaochun.jiankangapp.base.BaseActivity
import com.xiaochun.jiankangapp.databinding.ActivityBodyInfoBinding
import com.xiaochun.jiankangapp.databinding.ListItemOtherChatBinding
import com.xiaochun.jiankangapp.databinding.ListItemOtherChatImageBinding
import com.xiaochun.jiankangapp.extension.onClick
import com.xiaochun.jiankangapp.extension.showToast
import com.xiaochun.jiankangapp.model.BodyInfoChatModel
import com.xiaochun.jiankangapp.model.BodyInfoItemModel
import com.xiaochun.jiankangapp.utils.DensityUtil
import com.xiaochun.jiankangapp.utils.RecorderUtil
import com.xiaochun.jiankangapp.utils.RecorderUtil.OnRecordListener
import com.xiaochun.jiankangapp.utils.VoicePlayer
import com.xiaochun.jiankangapp.viewmodel.BodyInfoViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import java.io.File
import kotlin.math.max
import kotlin.math.min

class BodyInfoActivity : BaseActivity() {
    private val viewModel: BodyInfoViewModel by viewModels()
    private val adapter: BodyInfoAdapter by lazy {
        BodyInfoAdapter()
    }
    lateinit var viewBinding: ActivityBodyInfoBinding
    private var mode = 1 //1文本 2语音

    @SuppressLint("UnsafeOptInUsageError")
    private val player = VoicePlayer()
    val record = RecorderUtil()
    private var needCancel = false

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        lifecycle.addObserver(player)
        viewBinding = setContentView<ActivityBodyInfoBinding>()
        viewBinding.send.onClick {
            val text = viewBinding.et.text.toString()
            if (text.isNullOrEmpty()) {
                showToast("请输入内容")
                return@onClick
            }
            showLoading()
            viewModel.save(BodyInfoChatModel(type = "one", content = text)) {
                hideLoading()
                if (it.isSuccessful) {
                    viewBinding.et.setText("")
                    showToast("发送成功")
                    it.data?.let {
                        adapter.add(it)
                    }
                } else {
                    showToast("发送失败，" + it.msg)
                }
            }
        }
        viewBinding.rv.adapter = adapter
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.RESUMED) {
                while (isActive) {
                    val r = viewModel.getList()
                    if (r.isSuccessful) {
                        val empty = adapter.itemCount == 0
                        adapter.setNewInstance(r.data ?: emptyList())
                        if (empty) {
                            scroll()
                        }
                    }
                    delay(5000)
                }
            }
        }
        viewBinding.mode.onClick {
            if (mode == 1) {
                mode = 2
            } else {
                mode = 1
            }
            if (mode == 1) {
                viewBinding.mode.setImageResource(R.mipmap.ic_voice)
                viewBinding.et.visibility = View.VISIBLE
                viewBinding.pressToSay.visibility = View.INVISIBLE
            } else {
                viewBinding.mode.setImageResource(R.mipmap.ic_keyboard)
                viewBinding.et.visibility = View.INVISIBLE
                viewBinding.pressToSay.visibility = View.VISIBLE

            }
        }
        record.setOnRecordListener(object : OnRecordListener {
            override fun onVoiceChanged(vuSize: Int, max_vu_size: Int) {
            }

            override fun onAutoStopRecord(filePath: String?, duation: Long) {
                if (needCancel) {
                    return
                }
                if (!filePath.isNullOrEmpty()) {
                    lifecycleScope.launch {
                        showLoading()
                        val r = upload(File(filePath))
                        if (r.isSuccessful) {
                            viewModel.save(
                                BodyInfoChatModel(
                                    type = "two",
                                    content = r.data?.url ?: ""
                                )
                            ) {
                                if (it.isSuccessful) {
                                    showToast("发送成功")
                                    it.data?.let {
                                        adapter.add(it)
                                    }
                                } else {
                                    showToast("发送失败，" + it.msg)
                                }
                                hideLoading()
                            }
                        } else {
                            hideLoading()
                            showToast("上传失败，" + r.msg)
                        }

                    }
                }
            }

            override fun onTimeUsing(nowTimeSecond: Int) {
            }

        })
        viewBinding.pressToSay.setOnTouchListener { v, event ->
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    val p = ContextCompat.checkSelfPermission(
                        this,
                        Manifest.permission.RECORD_AUDIO
                    ) == PackageManager.PERMISSION_GRANTED
                    if (!p) {
                        requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), 1000)
                        return@setOnTouchListener false
                    }
                    viewBinding.recording.visibility = View.VISIBLE
                    record.startRecording()
                }

                MotionEvent.ACTION_MOVE -> {
                    if (isTouchInViews(event, viewBinding.cancel)) {
                        needCancel = true
                        viewBinding.tvrecord.text = "取消发送"
                    } else {
                        needCancel = false
                        viewBinding.tvrecord.text = "松开发送"
                    }
                }

                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    record.stopRecording()
                    viewBinding.recording.visibility = View.GONE

                }
            }
            true
        }
    }

    /**
     * 判断触摸的点是否在某个view的范围内
     *
     * @param event
     * @param view
     * @return
     */
    private fun isTouchInViews(event: MotionEvent, view: View): Boolean {
        val location = IntArray(2)
        view.getLocationOnScreen(location)
        val x = event.rawX
        val y = event.rawY
        val locationX = location[0]
        val locationY = location[1]
        val xIn = x > locationX && x < locationX + view.width
        val yIn = y > locationY && y < locationY + view.height
        return xIn && yIn
    }

    private fun scroll() {
        if (adapter.itemCount >= 1) {
            viewBinding.rv.scrollToPosition(adapter.itemCount - 1)
        }
    }


    inner class BodyInfoAdapter : Adapter<BaseBodyInfoItemViewHolder>() {
        private val list = mutableListOf<BodyInfoItemModel>()
        override fun onCreateViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): BaseBodyInfoItemViewHolder {
            return when (viewType) {
                1 -> {
                    return BodyInfoItemViewHolder(
                        this@BodyInfoActivity,
                        layoutInflater.inflate(
                            R.layout.list_item_self_chat,
                            parent,
                            false
                        )
                    )
                }

                200 -> {
                    return BodyInfoItemImageViewHolder(
                        this@BodyInfoActivity,
                        layoutInflater.inflate(
                            R.layout.list_item_other_chat_image,
                            parent,
                            false
                        )
                    )

                }

                else -> {
                    return BodyInfoItemViewHolder(
                        this@BodyInfoActivity,
                        layoutInflater.inflate(
                            R.layout.list_item_other_chat,
                            parent,
                            false
                        )
                    )

                }
            }
        }

        override fun getItemCount(): Int {
            return list.size
        }

        override fun onBindViewHolder(holder: BaseBodyInfoItemViewHolder, position: Int) {
            val item = list[position]
            holder.bind(item, position)
        }

        override fun getItemViewType(position: Int): Int {
            //one:用户 two:后台
            val item = list[position]
            return when (item.status) {
                "one" -> {
                    if (item.type == "three") {
                        100    //自己图
                    } else {
                        1    //自己文字
                    }

                }

                else -> {
                    if (item.type == "three") {
                        200 //其他人图
                    } else {
                        0 //其他人文字
                    }

                }
            }
        }


        fun setNewInstance(list: List<BodyInfoItemModel>) {
            this.list.clear()
            this.list.addAll(list)
            notifyDataSetChanged()
        }

        fun add(item: BodyInfoItemModel) {
            this.list.add(item)
            notifyDataSetChanged()
            scroll()
        }

    }

    abstract class BaseBodyInfoItemViewHolder(
        val bodyInfoActivity: BodyInfoActivity,
        itemView: View
    ) : ViewHolder(itemView) {
        fun bind(item: BodyInfoItemModel, position: Int) {
            when (item.status) {
                "one" -> { //用户
                    avatar?.setImageResource(if ("men" == item.sex) R.mipmap.man1 else R.mipmap.woman1)
                }

                "two" -> { //后台
                    avatar?.setImageResource(R.mipmap.avatar_doctor)
                }
            }
            onBind(item, position)
        }

        abstract fun onBind(item: BodyInfoItemModel, position: Int)
        val resources get() = itemView.resources

        abstract val avatar: ImageView?
    }

    class BodyInfoItemViewHolder(bodyInfoActivity: BodyInfoActivity, itemView: View) :
        BaseBodyInfoItemViewHolder(bodyInfoActivity, itemView) {
        val vb = ListItemOtherChatBinding.bind(itemView)
        override fun onBind(item: BodyInfoItemModel, position: Int) {
            vb.let {
                when (item.type) {
                    "one" -> { //文字
                        it.message.text = item.content
                        it.message.setCompoundDrawables(null, null, null, null)
                    }

                    "two" -> { //音频
                        it.message.text = "语音消息"
                        it.message.setCompoundDrawables(
                            resources.getDrawable(R.mipmap.voice_msg).apply {
                                setBounds(0, 0, intrinsicWidth, intrinsicHeight)
                            }, null, null, null
                        )
                    }
                }
                it.root.onClick {
                    when (item.type) {
                        "one" -> { //文字

                        }

                        "two" -> { //音频
                            bodyInfoActivity.player.startPlay(item.content)
                        }
                    }
                }
            }
        }

        override val avatar: ImageView?
            get() = vb.avatar
    }

    class BodyInfoItemImageViewHolder(bodyInfoActivity: BodyInfoActivity, itemView: View) :
        BaseBodyInfoItemViewHolder(bodyInfoActivity, itemView) {
        val vb = ListItemOtherChatImageBinding.bind(itemView)
        override fun onBind(item: BodyInfoItemModel, position: Int) {
            vb.message.let {
                calViewSize(it, item.width ?: 0, item.height ?: 0)
                Glide.with(bodyInfoActivity).load(item.content).into(it)
                vb.message.onClick {
                    ImagePreviewActivity.start(bodyInfoActivity, item.content)
                }
            }
        }

        val MAX_SIZE = 225f
        val MIN_SIZE = 120f
        private fun calViewSize(view: ImageView, imageWidth: Int, imageHeight: Int) {
            val mMaxSize = DensityUtil.dp2px(
                view.context,
                MAX_SIZE
            )
            val mMinSize = DensityUtil.dp2px(
                view.context,
                MIN_SIZE
            )
            var width = 0
            var height = 0
            if (imageWidth >= imageHeight) {
                if (imageWidth > mMaxSize) {
                    width = mMaxSize
                } else if (imageWidth < mMinSize) {
                    width = mMinSize
                } else {
                    width = min(imageWidth.toDouble(), mMaxSize.toDouble()).toInt()
                }
                height = (width * 1.0 / imageWidth * imageHeight).toInt()
                height = max(height.toDouble(), mMinSize.toDouble()).toInt()
            } else {
                if (imageHeight > mMaxSize) {
                    height = mMaxSize
                } else if (imageHeight < mMinSize) {
                    height = mMinSize
                } else {
                    height = min(imageHeight.toDouble(), mMaxSize.toDouble()).toInt()
                }
                width = (height * 1.0 / imageHeight * imageWidth).toInt()
                width = max(width.toDouble(), mMinSize.toDouble()).toInt()
            }
            val layoutParams = view.layoutParams
            layoutParams.width = width
            layoutParams.height = height
            view.layoutParams = layoutParams
        }

        override val avatar: ImageView?
            get() = vb.avatar
    }


}